<html>
<head><meta charset="utf-8"><title>rust-analyzer#923: producing nice code for refactorings · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html">rust-analyzer#923: producing nice code for refactorings</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="159863489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159863489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159863489">(Mar 03 2019 at 20:29)</a>:</h4>
<p>This is the stream to discuss <a href="https://github.com/rust-analyzer/rust-analyzer/issues/923" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/923">rust-analyzer#923</a>. This issue would be the beginning for the code formatting subsystem, so if you are into designing code formatters, feel free to suggest solutions!</p>



<a name="159911120"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911120" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911120">(Mar 04 2019 at 13:03)</a>:</h4>
<p>Hmm. Would it be bad to try to generalize rustfmt to be a library that could handle this problem?</p>



<a name="159911244"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911244" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911244">(Mar 04 2019 at 13:05)</a>:</h4>
<p>(It seems like the most interesting part, from an API design POV, is determining how to describe the context of the snippet of code you want to insert. Obviously you <em>could</em> just feed in the entire surrounding source code, but I would hope one could avoid it.)</p>



<a name="159911693"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911693" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911693">(Mar 04 2019 at 13:12)</a>:</h4>
<p>Yeah, this is about generalizing rustfmt essentially. That is, rustfmt2 should have an API for "reformat this syntax node"</p>



<a name="159911732"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911732" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911732">(Mar 04 2019 at 13:13)</a>:</h4>
<p>I don't think that feeding surrounding code is a problem per-se. Rather, it's <em>modifications</em> of surrounding code that we need to avoid</p>



<a name="159911812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911812">(Mar 04 2019 at 13:14)</a>:</h4>
<p>But it shouldn't be too hard to condense surrounding code to a description like "the indent level is N, the immediate predecessor has this type, the immediate successor has this type"</p>



<a name="159911844"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911844" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911844">(Mar 04 2019 at 13:14)</a>:</h4>
<p>(you need predecessor/successor information to add correct amount of whitespace <em>around</em> the newly inserted node)</p>



<a name="159911908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911908">(Mar 04 2019 at 13:15)</a>:</h4>
<p>And yeah, I think the red-green style syntax trees would be a good fit for rustfmt, so I game for rewriting rustfmt long/medium term as well =)</p>



<a name="159911913"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911913" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911913">(Mar 04 2019 at 13:15)</a>:</h4>
<p>How much do we want to specialize formatting for <code>rust-analyzer</code> ? Do we want to fix the simple common cases such as auto indenting but leave more advanced formatting for <code>rustfmt 2.0 API</code> ?</p>



<a name="159911963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911963">(Mar 04 2019 at 13:16)</a>:</h4>
<p>Specifically, currently rustfmt fails if there are syntax errors in the file, but, with rust-analyzer style trees, this should be easy to fix.</p>



<a name="159911984"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159911984" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159911984">(Mar 04 2019 at 13:16)</a>:</h4>
<p><span class="user-mention" data-user-id="204303">@vipentti</span> I think we should start with just auto-indenting</p>



<a name="159912013"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912013" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912013">(Mar 04 2019 at 13:16)</a>:</h4>
<p>When we finalize the syntax-tree data structure, I think we should rewrite rustmft</p>



<a name="159912151"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912151" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912151">(Mar 04 2019 at 13:18)</a>:</h4>
<p>Hmm, could the formatting benefit from implementing some structured editing API in <a href="https://github.com/rust-analyzer/rust-analyzer/issues/779" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/779">rust-analyzer#779</a> ?</p>



<a name="159912237"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912237" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912237">(Mar 04 2019 at 13:19)</a>:</h4>
<p><span class="user-mention" data-user-id="204303">@vipentti</span> I doubt it actually: formatting is mostly about modifying trivia, so structured editing does not help much</p>



<a name="159912316"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912316" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912316">(Mar 04 2019 at 13:20)</a>:</h4>
<p>There are cases like "adding trailing comma", where structured editing would be helpful, but there aren't too many such cases.</p>



<a name="159912336"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912336" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912336">(Mar 04 2019 at 13:20)</a>:</h4>
<p>indentation and line breaking are much more difficult parts of code formatting.</p>



<a name="159912576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912576">(Mar 04 2019 at 13:23)</a>:</h4>
<p>Would we want to "fix" wrong indentation as well ? e.g.</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Bar</span><span class="p">;</span><span class="w"></span>

<span class="w">                         </span><span class="k">impl</span><span class="w"> </span><span class="n">Bar</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="159912671"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912671" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912671">(Mar 04 2019 at 13:24)</a>:</h4>
<p>(when using <code>add-impl</code> for example)</p>



<a name="159912677"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912677" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912677">(Mar 04 2019 at 13:24)</a>:</h4>
<p>So, if <code>struct Bar</code> is pre-existing code, and <code>impl Bar</code> is the newly added code, we should not touch <code>struct Bar</code>, but we should properly indent <code>impl Bar</code></p>



<a name="159912931"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159912931" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159912931">(Mar 04 2019 at 13:28)</a>:</h4>
<p>I imagine this requires us to traverse up the tree to determine the actual indentation for the <code>impl Bar</code> unless we want to just indent it "properly" regards the <code>fn foo()</code> in this case. Which may or may not be properly indented itself</p>



<a name="159913106"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159913106" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159913106">(Mar 04 2019 at 13:30)</a>:</h4>
<div class="codehilite"><pre><span></span><span class="k">mod</span> <span class="nn">bar</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">struct</span> <span class="nc">Bar</span><span class="p">;</span><span class="w"> </span><span class="c1">// using add impl</span>
<span class="w">            </span><span class="k">impl</span><span class="w"> </span><span class="n">Bar</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Gets indented here</span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="159913111"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159913111" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159913111">(Mar 04 2019 at 13:30)</a>:</h4>
<p>I think indentation should be relative to the parent item.</p>



<a name="159913164"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/159913164" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#159913164">(Mar 04 2019 at 13:31)</a>:</h4>
<p>That is, we traverse not to the root, but to the "owner" node (<code>ast::Block</code> in this case), and figure out the indentation relative to that</p>



<a name="162350998"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162350998" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162350998">(Apr 02 2019 at 16:29)</a>:</h4>
<p>I'm interested in taking a look into this. I'm going to see where I get with replicating the tests linked in the issue and then report back.</p>



<a name="162351203"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162351203" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162351203">(Apr 02 2019 at 16:31)</a>:</h4>
<p>Cool! just yesterday I was looking at various assits, whihc have formatting code, <a href="https://github.com/rust-analyzer/rust-analyzer/blob/5cdf525caa51311515854c4dd398d3fb907d1368/crates/ra_assists/src/introduce_variable.rs#L53-L65" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/blob/5cdf525caa51311515854c4dd398d3fb907d1368/crates/ra_assists/src/introduce_variable.rs#L53-L65">like this</a> interspersed with the logic. It would be awesome to get rid of this!</p>



<a name="162351369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162351369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162351369">(Apr 02 2019 at 16:33)</a>:</h4>
<p>Thanks for the heads up, I'm going to start by looking for instances of that I think about how that could be reused. Then, I'll come up with something and seek feedback on my approach.</p>



<a name="162351723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162351723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162351723">(Apr 02 2019 at 16:37)</a>:</h4>
<p>That is, something like "introduce a variable"  should produce a poorly-formatted syntax tree with variable inserted, ask the formatting subsystem to fix this single node, and use the fixed result as the final result.</p>



<a name="162352507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352507">(Apr 02 2019 at 16:49)</a>:</h4>
<p>So, in this case,</p>
<div class="codehilite"><pre><span></span><span class="k">mod</span> <span class="nn">g</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">struct</span> <span class="nc">A</span><span class="o">&lt;|&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>

<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p><em>Add derive</em></p>
<div class="codehilite"><pre><span></span><span class="k">mod</span> <span class="nn">g</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="cp">#[derive(&lt;|&gt;)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">A</span><span class="w"> </span><span class="p">{</span><span class="w"></span>

<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>I should think about it more like: <br>
 1. Insert the necessary symbols (produces what is seen above) and then<br>
 2. Look at formatting just the <code>    #[derive(&lt;|&gt;)]</code> to <code>    }</code> lines?</p>



<a name="162352640"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352640" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352640">(Apr 02 2019 at 16:50)</a>:</h4>
<p>And perhaps look into a way to input the parent node as a parameter to gain indentation information from?</p>



<a name="162352664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352664">(Apr 02 2019 at 16:50)</a>:</h4>
<p>yeah, perhaps at just reformatting the derived node</p>



<a name="162352722"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352722" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352722">(Apr 02 2019 at 16:51)</a>:</h4>
<p>That is, the assist should produce</p>
<div class="codehilite"><pre><span></span>mod g {
       #[derive()] struct A {
       }
}
</pre></div>


<p>and formatter should add a newline</p>



<a name="162352798"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352798" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352798">(Apr 02 2019 at 16:52)</a>:</h4>
<p>Nodes know their parents, so it is always possible to take a look at the context</p>



<a name="162352805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352805">(Apr 02 2019 at 16:52)</a>:</h4>
<p>In the end, we could simply remove the whitespace counting code (like the one you referenced just a moment ago), and format.</p>



<a name="162352903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162352903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162352903">(Apr 02 2019 at 16:53)</a>:</h4>
<p>Do you think I'd be able to simply leverage the existing fmt code in RA? Or would some modifications need to be made?</p>



<a name="162353024"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353024" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353024">(Apr 02 2019 at 16:54)</a>:</h4>
<p>I am afraid pretty substantial modifications would be needed, if we want ot reuse rustfmt</p>



<a name="162353068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353068">(Apr 02 2019 at 16:55)</a>:</h4>
<p>feature wise,</p>
<ul>
<li>we should be able to format an isolated node (as opposed to the whole file)</li>
<li>we should be able to format code, even if it contains syntax errors</li>
</ul>



<a name="162353085"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353085" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353085">(Apr 02 2019 at 16:55)</a>:</h4>
<p>These two points imply that we should use our syntax tree for formatting</p>



<a name="162353150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353150">(Apr 02 2019 at 16:56)</a>:</h4>
<p>and changing rustfmt's syntax tree would be a huge task</p>



<a name="162353189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353189">(Apr 02 2019 at 16:56)</a>:</h4>
<p>So, I think it makes sense to start experimenting with from-scratch formatter which does only subset of things</p>



<a name="162353198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353198">(Apr 02 2019 at 16:56)</a>:</h4>
<p>to nail down the API, etc.</p>



<a name="162353232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353232">(Apr 02 2019 at 16:57)</a>:</h4>
<p>after we are comfortable with that, I'd game for just rewriting rustfmt as a library on top of ra_syntax</p>



<a name="162353530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353530">(Apr 02 2019 at 17:00)</a>:</h4>
<p>Okay, that sounds like a good long-term plan. For now, perhaps I'll start looking at creating a simple function which takes in the node to be formatted. For now, this function will correct whitespace issues, but it will be designed to eventually support large parts of rustfmt's capabilities</p>



<a name="162353575"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353575" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353575">(Apr 02 2019 at 17:01)</a>:</h4>
<p>sgtm!</p>



<a name="162353610"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353610" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353610">(Apr 02 2019 at 17:01)</a>:</h4>
<p>In RA, would it be more common to mutate the node, return back a clone with changes, or return a diff to be applied?</p>



<a name="162353736"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353736" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353736">(Apr 02 2019 at 17:02)</a>:</h4>
<p>I haven't started looking deeply into it, yet. But if we can retrieve the parent node from a child node, it seems like it could be a simple <code>fn format(&amp;config, &amp;node) -&gt; Node</code><br>
Or maybe for now, <code>fn format(&amp;node) -&gt; Node</code></p>



<a name="162353903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353903">(Apr 02 2019 at 17:04)</a>:</h4>
<p>I'll leave the configuration passing choices up for a later discussion...</p>



<a name="162353920"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353920" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353920">(Apr 02 2019 at 17:04)</a>:</h4>
<p>That is a good question, which I feel would be the core of the design. </p>
<p>Syntax trees in Rust-Analyzer are an immutable data structure, so you can't mutate them in place. You can, however, cheaply create a copy of a file with some subtree substituted.</p>



<a name="162353988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162353988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162353988">(Apr 02 2019 at 17:05)</a>:</h4>
<p>Can I create a copy of a node with a <em>child</em> node replaced <em>cheaply</em>?</p>



<a name="162354073"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354073" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354073">(Apr 02 2019 at 17:06)</a>:</h4>
<p>I feel formatting should be split into two bits:</p>
<ul>
<li>adjustting whitespace</li>
<li>tree transformations (for example, adding traling commas)</li>
</ul>
<p>For adjusting ws, I think a nice API would be to walk a tree and compute, for each whitespace token, and edit whihc should be applied to each token</p>



<a name="162354089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354089">(Apr 02 2019 at 17:06)</a>:</h4>
<p>yeah, you can replace children cheaply</p>



<a name="162354114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354114">(Apr 02 2019 at 17:06)</a>:</h4>
<p>Though, there's really no good high-level API for it</p>



<a name="162354145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354145">(Apr 02 2019 at 17:07)</a>:</h4>
<p>you could take a look at the <code>reparsing</code> module, which does tree modification for incremental reparsing</p>



<a name="162354337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354337">(Apr 02 2019 at 17:09)</a>:</h4>
<p>I also feel that for formatting specifically, a <strong>mutable</strong> tree might be a good fit.</p>
<p>Formatting than could be cast as applyng a series of transformations until a fixed point. That is, you can, for example, traverse the tree, apply the required indent as you go, and looking at the parent indent, without maintaining an explicit diff</p>



<a name="162354356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354356">(Apr 02 2019 at 17:09)</a>:</h4>
<p>It's interesting that IntellIJ, for formatting, builds a separate so-called formatting block tree, and runs on it</p>



<a name="162354414"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354414" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354414">(Apr 02 2019 at 17:10)</a>:</h4>
<p>Is it trivial to track cursor location in the existing node structures?</p>



<a name="162354429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354429">(Apr 02 2019 at 17:10)</a>:</h4>
<blockquote>
<p>Is it trivial to track cursor location in the existing node structures?</p>
</blockquote>
<p>now</p>



<a name="162354444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354444">(Apr 02 2019 at 17:10)</a>:</h4>
<p>In general, tracking anything after edit is hard</p>



<a name="162354477"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354477" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354477">(Apr 02 2019 at 17:11)</a>:</h4>
<p>The problem is, when you replace a node, you get back a file, and you need to find the "clone" of the node in it yourself</p>



<a name="162354598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354598">(Apr 02 2019 at 17:12)</a>:</h4>
<p>I could definitely see this mutable tree structure (similar to IntelliJ's) also being able to keep track of the cursor.<br>
Especially since assists provide cursor locations after application, and if you reformat your file, it'd be nice to not lose your cursor location.</p>



<a name="162354609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354609">(Apr 02 2019 at 17:12)</a>:</h4>
<p>I think it would be a good idea to take a closer look at IntelliJ's formatted: <a href="https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/formatter.html" target="_blank" title="https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/formatter.html">https://www.jetbrains.org/intellij/sdk/docs/tutorials/custom_language_support/formatter.html</a>. Not that it has good docs :)</p>



<a name="162354627"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354627" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354627">(Apr 02 2019 at 17:12)</a>:</h4>
<p>I don't quite sure I have a full picture of what is available, but that's my first thought.</p>



<a name="162354664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354664">(Apr 02 2019 at 17:13)</a>:</h4>
<p>I'll look into that formatter reference. I'm sure I'll get a few ideas</p>



<a name="162354684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354684">(Apr 02 2019 at 17:13)</a>:</h4>
<p>To be fair, I also don't quite understand how this formatting API should look like. I guess we'll have to churn through a couple of different approaches before we find a good one!</p>



<a name="162354765"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162354765" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162354765">(Apr 02 2019 at 17:14)</a>:</h4>
<p>I'm completely on board with trial-and-error</p>



<a name="162355161"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355161" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355161">(Apr 02 2019 at 17:18)</a>:</h4>
<p>The more I think about it, the more I like the idea of creating a mutable formatting tree on top of immutable syntax tree, and working with that...</p>
<p>That should give us a pretty flexible API.</p>



<a name="162355409"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355409" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355409">(Apr 02 2019 at 17:21)</a>:</h4>
<p>So formatting works like this:</p>
<ul>
<li>you get a node to reformat</li>
<li>you create a shadow formatting tree, whihch wraps any non-ws elment of the original tree, and which represents spacing explicitelly (like, ws is not a string, but an indent level, etc)</li>
<li>formatting code mutates spacing in the formatting tree. If it wants to, it can examing original nodes (with a caveat that they are in the orginial state)</li>
<li>after formatting tree is in a good shapre, formatter walks both trees in lockstep, and computes the edit for the diff</li>
</ul>



<a name="162355512"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355512" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355512">(Apr 02 2019 at 17:22)</a>:</h4>
<p>A good thing would be if trailing whitespaces are unrepresentable in the format tree :D</p>



<a name="162355565"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355565" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355565">(Apr 02 2019 at 17:23)</a>:</h4>
<p>"computes the edit for the diff" would the diff be a vec of AtomicTextEdits?</p>



<a name="162355594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355594">(Apr 02 2019 at 17:23)</a>:</h4>
<p>yeah</p>



<a name="162355653"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355653" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355653">(Apr 02 2019 at 17:24)</a>:</h4>
<p>fundamtelly, the result of any operation should be a diff, b/c that's what we send to the client</p>



<a name="162355659"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355659" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355659">(Apr 02 2019 at 17:24)</a>:</h4>
<p>but I think it's a good idea to work with a stateful trees internally</p>



<a name="162355784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355784">(Apr 02 2019 at 17:26)</a>:</h4>
<p>Why not track ws in the shadow formatting tree? Then, we could simply update the ws nodes as we walk through the tree...</p>



<a name="162355842"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355842" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355842">(Apr 02 2019 at 17:27)</a>:</h4>
<p>I'm thinking that the whitespace could potentially influence the resulting format.</p>



<a name="162355929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355929">(Apr 02 2019 at 17:28)</a>:</h4>
<p>A good example of this is <code>dartfmt</code> which gives the author a lot of control over the formatting by preserving some whitespacing and correcting others based on that.</p>



<a name="162355949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162355949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162355949">(Apr 02 2019 at 17:28)</a>:</h4>
<p><a href="https://github.com/dart-lang/dart_style#readme" target="_blank" title="https://github.com/dart-lang/dart_style#readme">https://github.com/dart-lang/dart_style#readme</a></p>



<a name="162356173"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162356173" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162356173">(Apr 02 2019 at 17:31)</a>:</h4>
<p>Anyway, just a trail of thoughts. We won't know much until I've banged around in the code for a little bit ;-)</p>



<a name="162356194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162356194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162356194">(Apr 02 2019 at 17:31)</a>:</h4>
<p>We should track ws in shadow tree, but we should track it in a more structured way</p>



<a name="162356291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162356291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162356291">(Apr 02 2019 at 17:32)</a>:</h4>
<p>or maybe not, I don't know.</p>
<p>What I know is that the repr in syntax tree, where ws is just a string, is annoying to work with, because computing indent  is a pain.</p>



<a name="162356654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162356654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162356654">(Apr 02 2019 at 17:37)</a>:</h4>
<p>That makes sense to me</p>



<a name="162356799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162356799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162356799">(Apr 02 2019 at 17:39)</a>:</h4>
<p><span class="user-mention" data-user-id="215394">@Cole Lawrence</span> I guess a concrete first step here is to think hard about the problem, identify a small slice we can tackle and open a GitHub issue with the design/PR. Oh, and INtelliJ Rust formatter is here, if I haven't linked it before: <a href="https://github.com/intellij-rust/intellij-rust/tree/master/src/main/kotlin/org/rust/ide/formatter" target="_blank" title="https://github.com/intellij-rust/intellij-rust/tree/master/src/main/kotlin/org/rust/ide/formatter">https://github.com/intellij-rust/intellij-rust/tree/master/src/main/kotlin/org/rust/ide/formatter</a></p>



<a name="162362552"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162362552" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162362552">(Apr 02 2019 at 18:43)</a>:</h4>
<p>Does it make sense to consider macros at all at this point?</p>



<a name="162363142"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162363142" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162363142">(Apr 02 2019 at 18:50)</a>:</h4>
<p>Are there goals for others to extend rls? For example, to provide formatting for their macro libraries, or provide assistance for generating Serde serializers based on a JSON Schema?</p>



<a name="162372464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162372464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162372464">(Apr 02 2019 at 20:42)</a>:</h4>
<p>What does <code>compute_ws</code> do exactly? I'm having trouble understanding what purpose this has.</p>



<a name="162374053"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162374053" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162374053">(Apr 02 2019 at 21:02)</a>:</h4>
<p>Now, macros are definitely out of scope</p>



<a name="162374104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162374104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162374104">(Apr 02 2019 at 21:03)</a>:</h4>
<p>Compute_ws returns the space between two tokens. Like “no space before closing }</p>



<a name="162374181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162374181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162374181">(Apr 02 2019 at 21:04)</a>:</h4>
<p>As for the extension, that should be possible, but in a very far future:)</p>



<a name="162375906"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162375906" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162375906">(Apr 02 2019 at 21:27)</a>:</h4>
<p>I'm having a hard time understanding the relationship between HIR, AST, <code>SyntaxToken</code>s, and the "Source Text" (String) levels of representation.</p>
<p>My understanding is that our refactoring code currently (mostly) operates at the "Source Text" level, by looking at the derived HIR data (e.g. implementations, references, resolved type, etc.) AND THEN sending back up the changes to the raw "Source Text" directly.<br>
So...<br>
Would it be desirable to instead commit our refactorings at the HIR level, and then derive the necessary "Source Text" changes from the HIR tree changes?<br>
My thought process is that if we could refactor at the HIR level, we could theoretically <em>know</em> that the result will be "correct" (maybe incomplete).<br>
For example, "introduce as local variable" should be able to be applied to any expression, but identifying what are expressions at the "Source Text" level forces us to reimplement some of our parsing logic.<br>
This could also start to close the gap between compiler suggestions and the operations if compiler suggestions are communicated as HIR changes.</p>



<a name="162378743"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162378743" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Cole Lawrence <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162378743">(Apr 02 2019 at 22:13)</a>:</h4>
<p>For example, the way TypeScript handles the communication between codefixes and the compiler <a href="https://github.com/Microsoft/TypeScript/tree/master/src/services/codefixes" target="_blank" title="https://github.com/Microsoft/TypeScript/tree/master/src/services/codefixes">https://github.com/Microsoft/TypeScript/tree/master/src/services/codefixes</a></p>



<a name="162401502"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer%23923%3A%20producing%20nice%20code%20for%20refactorings/near/162401502" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/rust-analyzer.23923.3A.20producing.20nice.20code.20for.20refactorings.html#162401502">(Apr 03 2019 at 06:06)</a>:</h4>
<p>I would say that we have only two principally different levels of representation: Source and HIR.</p>
<p>For Source, we have several different views into the data: text (string), untyped SyntaxNode tree, typed tree of ast::FooBar values. However these are all views: there's one to one bidirectional correspondence between text and both trees (and typed tree uses literally the same representation as untyped tree). The core property of this layer is that it preserves all information from the source code exactly: all the comments and whitespace are in the tree.</p>
<p>HIR, in contrast, is by design a lossy implementation: different source might result in the same HIR. For this reason, it is important that the final transformation to source is computed at the level of the source code: if you transform HIR directly and map it back to source, you'll lose all the comments. </p>
<p>What we can and should do, though, is to use HIR to compute all the info, required to apply refactoring. See <a href="https://github.com/rust-analyzer/rust-analyzer/issues/1095" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/issues/1095">https://github.com/rust-analyzer/rust-analyzer/issues/1095</a> for an example of this. The struct fields example highlights the difference between HIR and source: when we add missing fields, we ideally should add them in the same order as the one in the struct declaration. However, HIR does not care about the order of fields, only syntax tree does. So, they need to work together to produce the desired result. </p>
<blockquote>
<p>but identifying what are expressions at the "Source Text" level forces us to reimplement some of our parsing logic.</p>
</blockquote>
<p>Note that this is not exactly what happens there: we should identify a specific expression at the cursor position, and that is very source-level specific. If the cursor is exactly between two nodes, you need to check both the left node and the right node, for example.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>